From 6f2b241b9f5da12cac0367b0a908857493e99bc0 Mon Sep 17 00:00:00 2001 From: Mike Boutin Date: Fri, 17 Jul 2015 19:41:56 -0400 Subject: [PATCH] Implement --color [auto|always|never]. Closes #1363. --- src/bin/bench.rs | 3 ++ src/bin/build.rs | 3 ++ src/bin/cargo.rs | 13 +++-- src/bin/clean.rs | 3 ++ src/bin/doc.rs | 3 ++ src/bin/fetch.rs | 11 +++-- src/bin/generate_lockfile.rs | 11 +++-- src/bin/git_checkout.rs | 9 ++-- src/bin/login.rs | 11 +++-- src/bin/new.rs | 3 ++ src/bin/owner.rs | 19 +++++--- src/bin/package.rs | 3 ++ src/bin/pkgid.rs | 11 +++-- src/bin/publish.rs | 17 ++++--- src/bin/read_manifest.rs | 7 ++- src/bin/run.rs | 3 ++ src/bin/rustc.rs | 3 ++ src/bin/search.rs | 11 +++-- src/bin/test.rs | 3 ++ src/bin/update.rs | 3 ++ src/bin/verify_project.rs | 3 ++ src/bin/version.rs | 5 +- src/bin/yank.rs | 17 ++++--- src/cargo/core/mod.rs | 2 +- src/cargo/core/shell.rs | 94 +++++++++++++++++++++--------------- src/cargo/lib.rs | 14 +++--- src/etc/_cargo | 21 ++++++++ src/etc/cargo.1 | 3 ++ src/etc/cargo.bashcomp.sh | 3 +- tests/test_shell.rs | 24 +++++---- 30 files changed, 226 insertions(+), 110 deletions(-) diff --git a/src/bin/bench.rs b/src/bin/bench.rs index 4b9d5164a..a1aabb89f 100644 --- a/src/bin/bench.rs +++ b/src/bin/bench.rs @@ -13,6 +13,7 @@ struct Options { flag_manifest_path: Option, flag_verbose: bool, flag_quiet: bool, + flag_color: Option, flag_lib: bool, flag_bin: Vec, flag_example: Vec, @@ -43,6 +44,7 @@ Options: --manifest-path PATH Path to the manifest to build benchmarks for -v, --verbose Use verbose output -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never All of the trailing arguments are passed to the benchmark binaries generated for filtering benchmarks and generally providing options configuring how they @@ -62,6 +64,7 @@ Compilation can be customized with the `bench` profile in the manifest. pub fn execute(options: Options, config: &Config) -> CliResult> { let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); + try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..]))); let ops = ops::TestOptions { no_run: options.flag_no_run, diff --git a/src/bin/build.rs b/src/bin/build.rs index 0ba089e1b..577baa490 100644 --- a/src/bin/build.rs +++ b/src/bin/build.rs @@ -15,6 +15,7 @@ struct Options { flag_manifest_path: Option, flag_verbose: bool, flag_quiet: bool, + flag_color: Option, flag_release: bool, flag_lib: bool, flag_bin: Vec, @@ -45,6 +46,7 @@ Options: --manifest-path PATH Path to the manifest to compile -v, --verbose Use verbose output -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never If the --package argument is given, then SPEC is a package id specification which indicates which package should be built. If it is not given, then the @@ -60,6 +62,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { debug!("executing; cmd=cargo-build; args={:?}", env::args().collect::>()); try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); + try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..]))); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); diff --git a/src/bin/cargo.rs b/src/bin/cargo.rs index 73646756d..bfa763852 100644 --- a/src/bin/cargo.rs +++ b/src/bin/cargo.rs @@ -21,6 +21,7 @@ struct Flags { flag_list: bool, flag_verbose: bool, flag_quiet: bool, + flag_color: Option, arg_command: String, arg_args: Vec, } @@ -33,11 +34,12 @@ Usage: cargo [options] Options: - -h, --help Display this message - -V, --version Print version info and exit - --list List installed commands - -v, --verbose Use verbose output - -q, --quiet No output printed to stdout + -h, --help Display this message + -V, --version Print version info and exit + --list List installed commands + -v, --verbose Use verbose output + -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never Some common cargo commands are: build Compile the current project @@ -92,6 +94,7 @@ macro_rules! each_subcommand{ ($mac:ident) => ({ */ fn execute(flags: Flags, config: &Config) -> CliResult> { try!(config.shell().set_verbosity(flags.flag_verbose, flags.flag_quiet)); + try!(config.shell().set_color_config(flags.flag_color.as_ref().map(|s| &s[..]))); init_git_transports(config); diff --git a/src/bin/clean.rs b/src/bin/clean.rs index 825d05c71..18c6111e5 100644 --- a/src/bin/clean.rs +++ b/src/bin/clean.rs @@ -11,6 +11,7 @@ struct Options { flag_manifest_path: Option, flag_verbose: bool, flag_quiet: bool, + flag_color: Option, } pub const USAGE: &'static str = " @@ -26,6 +27,7 @@ Options: --target TRIPLE Target triple to clean output for (default all) -v, --verbose Use verbose output -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never If the --package argument is given, then SPEC is a package id specification which indicates which package's artifacts should be cleaned out. If it is not @@ -35,6 +37,7 @@ and its format, see the `cargo help pkgid` command. pub fn execute(options: Options, config: &Config) -> CliResult> { try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); + try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..]))); debug!("executing; cmd=cargo-clean; args={:?}", env::args().collect::>()); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); diff --git a/src/bin/doc.rs b/src/bin/doc.rs index 157f3f393..6bc43a86b 100644 --- a/src/bin/doc.rs +++ b/src/bin/doc.rs @@ -13,6 +13,7 @@ struct Options { flag_open: bool, flag_verbose: bool, flag_quiet: bool, + flag_color: Option, flag_package: Option, } @@ -34,6 +35,7 @@ Options: --manifest-path PATH Path to the manifest to document -v, --verbose Use verbose output -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never By default the documentation for the local package and all dependencies is built. The output is all placed in `target/doc` in rustdoc's usual format. @@ -46,6 +48,7 @@ the `cargo help pkgid` command. pub fn execute(options: Options, config: &Config) -> CliResult> { try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); + try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..]))); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); diff --git a/src/bin/fetch.rs b/src/bin/fetch.rs index 3c8ecbdc4..94087f026 100644 --- a/src/bin/fetch.rs +++ b/src/bin/fetch.rs @@ -7,6 +7,7 @@ struct Options { flag_manifest_path: Option, flag_verbose: bool, flag_quiet: bool, + flag_color: Option, } pub const USAGE: &'static str = " @@ -16,10 +17,11 @@ Usage: cargo fetch [options] Options: - -h, --help Print this message - --manifest-path PATH Path to the manifest to fetch dependencies for - -v, --verbose Use verbose output - -q, --quiet No output printed to stdout + -h, --help Print this message + --manifest-path PATH Path to the manifest to fetch dependencies for + -v, --verbose Use verbose output + -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never If a lockfile is available, this command will ensure that all of the git dependencies and/or registries dependencies are downloaded and locally @@ -33,6 +35,7 @@ all updated. pub fn execute(options: Options, config: &Config) -> CliResult> { try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); + try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..]))); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); try!(ops::fetch(&root, config).map_err(|e| { CliError::from_boxed(e, 101) diff --git a/src/bin/generate_lockfile.rs b/src/bin/generate_lockfile.rs index bb2ade5fe..29891f1c8 100644 --- a/src/bin/generate_lockfile.rs +++ b/src/bin/generate_lockfile.rs @@ -9,6 +9,7 @@ struct Options { flag_manifest_path: Option, flag_verbose: bool, flag_quiet: bool, + flag_color: Option, } pub const USAGE: &'static str = " @@ -18,15 +19,17 @@ Usage: cargo generate-lockfile [options] Options: - -h, --help Print this message - --manifest-path PATH Path to the manifest to generate a lockfile for - -v, --verbose Use verbose output - -q, --quiet No output printed to stdout + -h, --help Print this message + --manifest-path PATH Path to the manifest to generate a lockfile for + -v, --verbose Use verbose output + -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never "; pub fn execute(options: Options, config: &Config) -> CliResult> { debug!("executing; cmd=cargo-generate-lockfile; args={:?}", env::args().collect::>()); try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); + try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..]))); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); ops::generate_lockfile(&root, config) diff --git a/src/bin/git_checkout.rs b/src/bin/git_checkout.rs index eaf1df367..ff4d5f4c4 100644 --- a/src/bin/git_checkout.rs +++ b/src/bin/git_checkout.rs @@ -8,6 +8,7 @@ struct Options { flag_reference: String, flag_verbose: bool, flag_quiet: bool, + flag_color: Option, } pub const USAGE: &'static str = " @@ -16,13 +17,15 @@ Usage: cargo git-checkout -h | --help Options: - -h, --help Print this message - -v, --verbose Use verbose output - -q, --quiet No output printed to stdout + -h, --help Print this message + -v, --verbose Use verbose output + -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never "; pub fn execute(options: Options, config: &Config) -> CliResult> { try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); + try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..]))); let Options { flag_url: url, flag_reference: reference, .. } = options; let url = try!(url.to_url().map_err(|e| { diff --git a/src/bin/login.rs b/src/bin/login.rs index a0ec4bfea..bfcc2f8ae 100644 --- a/src/bin/login.rs +++ b/src/bin/login.rs @@ -12,6 +12,7 @@ struct Options { arg_token: Option, flag_verbose: bool, flag_quiet: bool, + flag_color: Option, } pub const USAGE: &'static str = " @@ -21,15 +22,17 @@ Usage: cargo login [options] [] Options: - -h, --help Print this message - --host HOST Host to set the token for - -v, --verbose Use verbose output - -q, --quiet No output printed to stdout + -h, --help Print this message + --host HOST Host to set the token for + -v, --verbose Use verbose output + -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never "; pub fn execute(options: Options, config: &Config) -> CliResult> { try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); + try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..]))); let token = match options.arg_token.clone() { Some(token) => token, None => { diff --git a/src/bin/new.rs b/src/bin/new.rs index 6c1b6598c..0c6864448 100644 --- a/src/bin/new.rs +++ b/src/bin/new.rs @@ -7,6 +7,7 @@ use cargo::util::{CliResult, CliError, Config}; struct Options { flag_verbose: bool, flag_quiet: bool, + flag_color: Option, flag_bin: bool, arg_path: String, flag_name: Option, @@ -29,11 +30,13 @@ Options: --name Set the resulting package name -v, --verbose Use verbose output -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never "; pub fn execute(options: Options, config: &Config) -> CliResult> { debug!("executing; cmd=cargo-new; args={:?}", env::args().collect::>()); try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); + try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..]))); let Options { flag_bin, arg_path, flag_name, flag_vcs, .. } = options; diff --git a/src/bin/owner.rs b/src/bin/owner.rs index 598555a9a..cf2ca2ec6 100644 --- a/src/bin/owner.rs +++ b/src/bin/owner.rs @@ -10,6 +10,7 @@ struct Options { flag_index: Option, flag_verbose: bool, flag_quiet: bool, + flag_color: Option, flag_list: bool, } @@ -20,14 +21,15 @@ Usage: cargo owner [options] [] Options: - -h, --help Print this message - -a, --add LOGIN Login of a user to add as an owner - -r, --remove LOGIN Login of a user to remove as an owner - -l, --list List owners of a crate - --index INDEX Registry index to modify owners for - --token TOKEN API token to use when authenticating - -v, --verbose Use verbose output - -q, --quiet No output printed to stdout + -h, --help Print this message + -a, --add LOGIN Login of a user to add as an owner + -r, --remove LOGIN Login of a user to remove as an owner + -l, --list List owners of a crate + --index INDEX Registry index to modify owners for + --token TOKEN API token to use when authenticating + -v, --verbose Use verbose output + -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never This command will modify the owners for a package on the specified registry (or default). Note that owners of a package can upload new versions, yank old @@ -36,6 +38,7 @@ versions, and also modify the set of owners, so take caution! pub fn execute(options: Options, config: &Config) -> CliResult> { try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); + try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..]))); let opts = ops::OwnersOptions { krate: options.arg_crate, token: options.flag_token, diff --git a/src/bin/package.rs b/src/bin/package.rs index 828fac3cc..4d3b72b71 100644 --- a/src/bin/package.rs +++ b/src/bin/package.rs @@ -6,6 +6,7 @@ use cargo::util::important_paths::find_root_manifest_for_cwd; struct Options { flag_verbose: bool, flag_quiet: bool, + flag_color: Option, flag_manifest_path: Option, flag_no_verify: bool, flag_no_metadata: bool, @@ -26,11 +27,13 @@ Options: --manifest-path PATH Path to the manifest to compile -v, --verbose Use verbose output -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never "; pub fn execute(options: Options, config: &Config) -> CliResult> { try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); + try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..]))); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); ops::package(&root, config, !options.flag_no_verify, diff --git a/src/bin/pkgid.rs b/src/bin/pkgid.rs index 400719e77..abbe4e52f 100644 --- a/src/bin/pkgid.rs +++ b/src/bin/pkgid.rs @@ -6,6 +6,7 @@ use cargo::util::important_paths::{find_root_manifest_for_cwd}; struct Options { flag_verbose: bool, flag_quiet: bool, + flag_color: Option, flag_manifest_path: Option, arg_spec: Option, } @@ -17,10 +18,11 @@ Usage: cargo pkgid [options] [] Options: - -h, --help Print this message - --manifest-path PATH Path to the manifest to the package to clean - -v, --verbose Use verbose output - -q, --quiet No output printed to stdout + -h, --help Print this message + --manifest-path PATH Path to the manifest to the package to clean + -v, --verbose Use verbose output + -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never Given a argument, print out the fully qualified package id specifier. This command will generate an error if is ambiguous as to which package @@ -46,6 +48,7 @@ Example Package IDs pub fn execute(options: Options, config: &Config) -> CliResult> { try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); + try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..]))); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path.clone())); let spec = options.arg_spec.as_ref().map(|s| &s[..]); diff --git a/src/bin/publish.rs b/src/bin/publish.rs index 478947b44..387daecd2 100644 --- a/src/bin/publish.rs +++ b/src/bin/publish.rs @@ -9,6 +9,7 @@ struct Options { flag_manifest_path: Option, flag_verbose: bool, flag_quiet: bool, + flag_color: Option, flag_no_verify: bool, } @@ -19,18 +20,20 @@ Usage: cargo publish [options] Options: - -h, --help Print this message - --host HOST Host to upload the package to - --token TOKEN Token to use when uploading - --no-verify Don't verify package tarball before publish - --manifest-path PATH Path to the manifest to compile - -v, --verbose Use verbose output - -q, --quiet No output printed to stdout + -h, --help Print this message + --host HOST Host to upload the package to + --token TOKEN Token to use when uploading + --no-verify Don't verify package tarball before publish + --manifest-path PATH Path to the manifest to compile + -v, --verbose Use verbose output + -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never "; pub fn execute(options: Options, config: &Config) -> CliResult> { try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); + try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..]))); let Options { flag_token: token, flag_host: host, diff --git a/src/bin/read_manifest.rs b/src/bin/read_manifest.rs index bd8f9e366..591d9f42f 100644 --- a/src/bin/read_manifest.rs +++ b/src/bin/read_manifest.rs @@ -8,6 +8,7 @@ use cargo::sources::{PathSource}; #[derive(RustcDecodable)] struct Options { flag_manifest_path: String, + flag_color: Option, } pub const USAGE: &'static str = " @@ -16,11 +17,13 @@ Usage: cargo read-manifest -h | --help Options: - -h, --help Print this message - -v, --verbose Use verbose output + -h, --help Print this message + -v, --verbose Use verbose output + --color WHEN Coloring: auto, always, never "; pub fn execute(options: Options, config: &Config) -> CliResult> { + try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..]))); let path = Path::new(&options.flag_manifest_path); let mut source = try!(PathSource::for_path(&path, config).map_err(|e| { CliError::new(e.description(), 1) diff --git a/src/bin/run.rs b/src/bin/run.rs index 71718ef1d..7d411056a 100644 --- a/src/bin/run.rs +++ b/src/bin/run.rs @@ -13,6 +13,7 @@ struct Options { flag_manifest_path: Option, flag_verbose: bool, flag_quiet: bool, + flag_color: Option, flag_release: bool, arg_args: Vec, } @@ -35,6 +36,7 @@ Options: --manifest-path PATH Path to the manifest to execute -v, --verbose Use verbose output -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never If neither `--bin` nor `--example` are given, then if the project only has one bin target it will be run. Otherwise `--bin` specifies the bin target to run, @@ -46,6 +48,7 @@ All of the trailing arguments are passed to the binary to run. pub fn execute(options: Options, config: &Config) -> CliResult> { try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); + try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..]))); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); diff --git a/src/bin/rustc.rs b/src/bin/rustc.rs index 0292d79e7..920096c2b 100644 --- a/src/bin/rustc.rs +++ b/src/bin/rustc.rs @@ -16,6 +16,7 @@ struct Options { flag_manifest_path: Option, flag_verbose: bool, flag_quiet: bool, + flag_color: Option, flag_release: bool, flag_lib: bool, flag_bin: Vec, @@ -46,6 +47,7 @@ Options: --manifest-path PATH Path to the manifest to fetch dependencies for -v, --verbose Use verbose output -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never The specified target for the current package (or package specified by SPEC if provided) will be compiled along with all of its dependencies. The specified @@ -63,6 +65,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { debug!("executing; cmd=cargo-rustc; args={:?}", env::args().collect::>()); try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); + try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..]))); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); diff --git a/src/bin/search.rs b/src/bin/search.rs index 8710f546d..05c547585 100644 --- a/src/bin/search.rs +++ b/src/bin/search.rs @@ -6,6 +6,7 @@ struct Options { flag_host: Option, flag_verbose: bool, flag_quiet: bool, + flag_color: Option, arg_query: String } @@ -17,14 +18,16 @@ Usage: cargo search [-h | --help] Options: - -h, --help Print this message - --host HOST Host of a registry to search in - -v, --verbose Use verbose output - -q, --quiet No output printed to stdout + -h, --help Print this message + --host HOST Host of a registry to search in + -v, --verbose Use verbose output + -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never "; pub fn execute(options: Options, config: &Config) -> CliResult> { try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); + try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..]))); let Options { flag_host: host, arg_query: query, diff --git a/src/bin/test.rs b/src/bin/test.rs index aafa8ec1c..44b6c60c8 100644 --- a/src/bin/test.rs +++ b/src/bin/test.rs @@ -19,6 +19,7 @@ struct Options { flag_bench: Vec, flag_verbose: bool, flag_quiet: bool, + flag_color: Option, flag_release: bool, } @@ -45,6 +46,7 @@ Options: --manifest-path PATH Path to the manifest to build tests for -v, --verbose Use verbose output -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never All of the trailing arguments are passed to the test binaries generated for filtering tests and generally providing options configuring how they run. For @@ -66,6 +68,7 @@ Compilation can be configured via the `test` profile in the manifest. pub fn execute(options: Options, config: &Config) -> CliResult> { let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); + try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..]))); let ops = ops::TestOptions { no_run: options.flag_no_run, diff --git a/src/bin/update.rs b/src/bin/update.rs index f1956566b..cd4cd1173 100644 --- a/src/bin/update.rs +++ b/src/bin/update.rs @@ -12,6 +12,7 @@ struct Options { flag_manifest_path: Option, flag_verbose: bool, flag_quiet: bool, + flag_color: Option, } pub const USAGE: &'static str = " @@ -28,6 +29,7 @@ Options: --manifest-path PATH Path to the manifest to compile -v, --verbose Use verbose output -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never This command requires that a `Cargo.lock` already exists as generated by `cargo build` or related commands. @@ -53,6 +55,7 @@ For more information about package id specifications, see `cargo help pkgid`. pub fn execute(options: Options, config: &Config) -> CliResult> { debug!("executing; cmd=cargo-update; args={:?}", env::args().collect::>()); try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); + try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..]))); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); let spec = options.flag_package.as_ref(); diff --git a/src/bin/verify_project.rs b/src/bin/verify_project.rs index 5b72f0667..b8d3f657c 100644 --- a/src/bin/verify_project.rs +++ b/src/bin/verify_project.rs @@ -14,6 +14,7 @@ struct Flags { flag_manifest_path: String, flag_verbose: bool, flag_quiet: bool, + flag_color: Option, } pub const USAGE: &'static str = " @@ -26,10 +27,12 @@ Options: --manifest-path PATH Path to the manifest to verify -v, --verbose Use verbose output -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never "; pub fn execute(args: Flags, config: &Config) -> CliResult> { try!(config.shell().set_verbosity(args.flag_verbose, args.flag_quiet)); + try!(config.shell().set_color_config(args.flag_color.as_ref().map(|s| &s[..]))); let mut contents = String::new(); let file = File::open(&args.flag_manifest_path); diff --git a/src/bin/version.rs b/src/bin/version.rs index b5622f225..12c954f58 100644 --- a/src/bin/version.rs +++ b/src/bin/version.rs @@ -11,8 +11,9 @@ Usage: cargo version [options] Options: - -h, --help Print this message - -v, --verbose Use verbose output + -h, --help Print this message + -v, --verbose Use verbose output + --color WHEN Coloring: auto, always, never "; pub fn execute(_: Options, _: &Config) -> CliResult> { diff --git a/src/bin/yank.rs b/src/bin/yank.rs index efd203261..d5322eb55 100644 --- a/src/bin/yank.rs +++ b/src/bin/yank.rs @@ -9,6 +9,7 @@ struct Options { flag_index: Option, flag_verbose: bool, flag_quiet: bool, + flag_color: Option, flag_undo: bool, } @@ -19,13 +20,14 @@ Usage: cargo yank [options] [] Options: - -h, --help Print this message - --vers VERSION The version to yank or un-yank - --undo Undo a yank, putting a version back into the index - --index INDEX Registry index to yank from - --token TOKEN API token to use when authenticating - -v, --verbose Use verbose output - -q, --quiet No output printed to stdout + -h, --help Print this message + --vers VERSION The version to yank or un-yank + --undo Undo a yank, putting a version back into the index + --index INDEX Registry index to yank from + --token TOKEN API token to use when authenticating + -v, --verbose Use verbose output + -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never The yank command removes a previously pushed crate's version from the server's index. This command does not delete any data, and the crate will still be @@ -38,6 +40,7 @@ crates to be locked to any yanked version. pub fn execute(options: Options, config: &Config) -> CliResult> { try!(config.shell().set_verbosity(options.flag_verbose, options.flag_quiet)); + try!(config.shell().set_color_config(options.flag_color.as_ref().map(|s| &s[..]))); try!(ops::yank(config, options.arg_crate, options.flag_vers, diff --git a/src/cargo/core/mod.rs b/src/cargo/core/mod.rs index f468f8c79..54c733348 100644 --- a/src/cargo/core/mod.rs +++ b/src/cargo/core/mod.rs @@ -5,7 +5,7 @@ pub use self::package_id::{PackageId, Metadata}; pub use self::package_id_spec::PackageIdSpec; pub use self::registry::Registry; pub use self::resolver::Resolve; -pub use self::shell::{Shell, MultiShell, ShellConfig, Verbosity}; +pub use self::shell::{Shell, MultiShell, ShellConfig, Verbosity, ColorConfig}; pub use self::source::{Source, SourceId, SourceMap, SourceSet, GitReference}; pub use self::summary::Summary; diff --git a/src/cargo/core/shell.rs b/src/cargo/core/shell.rs index ff5edba10..227261c8c 100644 --- a/src/cargo/core/shell.rs +++ b/src/cargo/core/shell.rs @@ -8,6 +8,7 @@ use term::{Terminal, TerminfoTerminal, color}; use self::AdequateTerminal::{NoColor, Colored}; use self::Verbosity::{Verbose, Normal, Quiet}; +use self::ColorConfig::{Auto, Always, Never}; use util::errors::{human, CargoResult}; @@ -18,10 +19,16 @@ pub enum Verbosity { Quiet } +#[derive(Clone, Copy, PartialEq)] +pub enum ColorConfig { + Auto, + Always, + Never +} + #[derive(Clone, Copy)] pub struct ShellConfig { - pub color: bool, - pub verbosity: Verbosity, + pub color_config: ColorConfig, pub tty: bool } @@ -115,6 +122,21 @@ impl MultiShell { } } + pub fn set_color_config(&mut self, color: Option<&str>) -> CargoResult<()> { + self.out.set_color_config(match color { + Some("auto") => Auto, + Some("always") => Always, + Some("never") => Never, + + None => Auto, + + Some(arg) => return Err(human(format!("argument for --color must be auto, always, or \ + never, but found `{}`", + arg))), + }); + Ok(()) + } + pub fn get_verbose(&self) -> Verbosity { self.verbosity } @@ -122,7 +144,9 @@ impl MultiShell { impl Shell { pub fn create(out: Box, config: ShellConfig) -> Shell { - if config.tty && config.color { + // Check for cfg!(windows) as colored output on Windows can only be supported when a tty is + // present. + if !cfg!(windows) || config.tty { let term = TerminfoTerminal::new(out); term.map(|t| Shell { terminal: Colored(Box::new(t)), @@ -135,36 +159,17 @@ impl Shell { } } - pub fn verbose(&mut self, mut callback: F) -> io::Result<()> - where F: FnMut(&mut Shell) -> io::Result<()> - { - match self.config.verbosity { - Verbose => return callback(self), - _ => Ok(()) - } - } - - pub fn concise(&mut self, mut callback: F) -> io::Result<()> - where F: FnMut(&mut Shell) -> io::Result<()> - { - match self.config.verbosity { - Verbose => Ok(()), - _ => return callback(self) - } + pub fn set_color_config(&mut self, color_config: ColorConfig) { + self.config.color_config = color_config; } pub fn say(&mut self, message: T, color: Color) -> io::Result<()> { - match self.config.verbosity { - Quiet => Ok(()), - _ => { - try!(self.reset()); - if color != BLACK { try!(self.fg(color)); } - try!(write!(self, "{}\n", message.to_string())); - try!(self.reset()); - try!(self.flush()); - Ok(()) - }, - } + try!(self.reset()); + if color != BLACK { try!(self.fg(color)); } + try!(write!(self, "{}\n", message.to_string())); + try!(self.reset()); + try!(self.flush()); + Ok(()) } pub fn say_status(&mut self, status: T, message: U, color: Color) @@ -182,32 +187,45 @@ impl Shell { } fn fg(&mut self, color: color::Color) -> io::Result { + let colored = self.colored(); + match self.terminal { - Colored(ref mut c) => c.fg(color), - NoColor(_) => Ok(false) + Colored(ref mut c) if colored => c.fg(color), + _ => Ok(false) } } fn attr(&mut self, attr: Attr) -> io::Result { + let colored = self.colored(); + match self.terminal { - Colored(ref mut c) => c.attr(attr), - NoColor(_) => Ok(false) + Colored(ref mut c) if colored => c.attr(attr), + _ => Ok(false) } } fn supports_attr(&self, attr: Attr) -> bool { + let colored = self.colored(); + match self.terminal { - Colored(ref c) => c.supports_attr(attr), - NoColor(_) => false + Colored(ref c) if colored => c.supports_attr(attr), + _ => false } } fn reset(&mut self) -> io::Result<()> { + let colored = self.colored(); + match self.terminal { - Colored(ref mut c) => c.reset().map(|_| ()), - NoColor(_) => Ok(()) + Colored(ref mut c) if colored => c.reset().map(|_| ()), + _ => Ok(()) } } + + fn colored(&self) -> bool { + self.config.tty && Auto == self.config.color_config + || Always == self.config.color_config + } } impl Write for Shell { diff --git a/src/cargo/lib.rs b/src/cargo/lib.rs index 1accb5e2c..669c5d5bf 100644 --- a/src/cargo/lib.rs +++ b/src/cargo/lib.rs @@ -31,8 +31,9 @@ use rustc_serialize::{Decodable, Encodable}; use rustc_serialize::json::{self, Json}; use docopt::Docopt; -use core::{Shell, MultiShell, ShellConfig, Verbosity}; +use core::{Shell, MultiShell, ShellConfig, Verbosity, ColorConfig}; use core::shell::Verbosity::{Verbose}; +use core::shell::ColorConfig::{Auto}; use term::color::{BLACK, RED}; pub use util::{CargoError, CliError, CliResult, human, Config, ChainError}; @@ -96,7 +97,7 @@ fn process(mut callback: F) { let mut config = None; let result = (|| { - config = Some(try!(Config::new(shell(Verbose)))); + config = Some(try!(Config::new(shell(Verbose, Auto)))); let args: Vec<_> = try!(env::args_os().map(|s| { s.into_string().map_err(|s| { human(format!("invalid unicode in argument: {:?}", s)) @@ -104,7 +105,7 @@ fn process(mut callback: F) }).collect()); callback(&args, config.as_ref().unwrap()) })(); - let mut verbose_shell = shell(Verbose); + let mut verbose_shell = shell(Verbose, Auto); let mut shell = config.as_ref().map(|s| s.shell()); let shell = shell.as_mut().map(|s| &mut **s).unwrap_or(&mut verbose_shell); process_executed(result, shell) @@ -123,17 +124,17 @@ pub fn process_executed(result: CliResult>, shell: &mut MultiShell) } } -pub fn shell(verbosity: Verbosity) -> MultiShell { +pub fn shell(verbosity: Verbosity, color_config: ColorConfig) -> MultiShell { let tty = isatty(libc::STDERR_FILENO); let stderr = Box::new(io::stderr()); - let config = ShellConfig { color: true, verbosity: verbosity, tty: tty }; + let config = ShellConfig { color_config: color_config, tty: tty }; let err = Shell::create(stderr, config); let tty = isatty(libc::STDOUT_FILENO); let stdout = Box::new(io::stdout()); - let config = ShellConfig { color: true, verbosity: verbosity, tty: tty }; + let config = ShellConfig { color_config: color_config, tty: tty }; let out = Shell::create(stdout, config); return MultiShell::new(out, err, verbosity); @@ -173,7 +174,6 @@ pub fn handle_error(err: CliError, shell: &mut MultiShell) { let CliError { error, exit_code, unknown } = err; let fatal = exit_code != 0; // exit_code == 0 is non-fatal error - let hide = unknown && shell.get_verbose() != Verbose; if hide { let _ = shell.err().say("An unknown error occurred", RED); diff --git a/src/etc/_cargo b/src/etc/_cargo index d85e5a785..a1c43aff8 100644 --- a/src/etc/_cargo +++ b/src/etc/_cargo @@ -9,6 +9,7 @@ _arguments \ '(- 1 *)'{-h,--help}'[show help message]' \ '(- 1 *)'--list'[list installed commands]' \ '(- 1 *)'{-v,--verbose}'[use verbose output]' \ + '(- 1 *)'--color'[colorization option]' \ '(- 1 *)'{-V,--version}'[show version information]' \ '1: :_cargo_cmds' \ '*:: :->args' @@ -29,6 +30,7 @@ case $state in '(-p,--package)'{-p=,--package=}'[package to run benchmarks for]:packages:_get_package_names' \ '--target=[target triple]' \ '(-v, --verbose)'{-v,--verbose}'[use verbose output]' \ + '--color=[colorization option]' \ ;; build) @@ -42,6 +44,7 @@ case $state in '--release=[build in release mode]' \ '--target=[target triple]' \ '(-v, --verbose)'{-v,--verbose}'[use verbose output]' \ + '--color=[colorization option]' \ ;; clean) @@ -51,6 +54,7 @@ case $state in '(-p,--package)'{-p=,--package=}'[package to clean]:packages:_get_package_names' \ '--target=[target triple(default:all)]' \ '(-v, --verbose)'{-v,--verbose}'[use verbose output]' \ + '--color=[colorization option]' \ ;; config-for-key) @@ -76,6 +80,7 @@ case $state in '--no-default-features[do not build the default features]' \ '--open[oen docs in browser after the build]' \ '(-v, --verbose)'{-v,--verbose}'[use verbose output]' \ + '--color=[colorization option]' \ ;; fetch) @@ -83,6 +88,7 @@ case $state in '(-h, --help)'{-h,--help}'[show help message]' \ '--manifest-path=[path to manifest]' \ '(-v, --verbose)'{-v,--verbose}'[use verbose output]' \ + '--color=[colorization option]' \ ;; generate-lockfile) @@ -90,6 +96,7 @@ case $state in '(-h, --help)'{-h,--help}'[show help message]' \ '--manifest-path=[path to manifest]' \ '(-v, --verbose)'{-v,--verbose}'[use verbose output]' \ + '--color=[colorization option]' \ ;; git-checkout) @@ -98,6 +105,7 @@ case $state in '--reference=[REF]' \ '--url=[URL]' \ '(-v, --verbose)'{-v,--verbose}'[use verbose output]' \ + '--color=[colorization option]' \ ;; help) @@ -117,6 +125,7 @@ case $state in '(-h, --help)'{-h,--help}'[show help message]' \ '--host=[Host to set the token for]' \ '(-v, --verbose)'{-v,--verbose}'[use verbose output]' \ + '--color=[colorization option]' \ ;; new) @@ -127,6 +136,7 @@ case $state in '--hg[initialize new mercurial repo]' \ '--no-git[no new git repo]' \ '(-v, --verbose)'{-v,--verbose}'[use verbose output]' \ + '--color=[colorization option]' \ ;; owner) @@ -137,6 +147,7 @@ case $state in '(-r, --remove)'{-r,--remove}'[remove owner LOGIN]' \ '--token[API token]' \ '(-v, --verbose)'{-v,--verbose}'[use verbose output]' \ + '--color=[colorization option]' \ ;; package) @@ -145,6 +156,7 @@ case $state in '--manifest-path=[path to manifest]' \ '--no-verify[do not build to verify contents]' \ '(-v, --verbose)'{-v,--verbose}'[use verbose output]' \ + '--color=[colorization option]' \ ;; pkgid) @@ -152,6 +164,7 @@ case $state in '(-h, --help)'{-h,--help}'[show help message]' \ '--manifest-path=[path to manifest]' \ '(-v, --verbose)'{-v,--verbose}'[use verbose output]' \ + '--color=[colorization option]' \ ;; publish) @@ -162,6 +175,7 @@ case $state in '--no-verify[Do not verify tarball until before publish]' \ '--token[Token to use when uploading]' \ '(-v, --verbose)'{-v,--verbose}'[use verbose output]' \ + '--color=[colorization option]' \ ;; read-manifest) @@ -169,6 +183,7 @@ case $state in '(-h, --help)'{-h,--help}'[show help message]' \ '--manifest-path=[path to manifest]' \ '(-v, --verbose)'{-v,--verbose}'[use verbose output]' \ + '--color=[colorization option]' \ ;; run) @@ -183,6 +198,7 @@ case $state in '--release=[build in release mode]' \ '--target=[target triple]' \ '(-v, --verbose)'{-v,--verbose}'[use verbose output]' \ + '--color=[colorization option]' \ '*: :_normal' \ ;; @@ -198,6 +214,7 @@ case $state in '(-p,--package)'{-p=,--package=}'[package to run tests for]:packages:_get_package_names' \ '--target=[target triple]' \ '(-v, --verbose)'{-v,--verbose}'[use verbose output]' \ + '--color=[colorization option]' \ '1: :_test_names' \ ;; @@ -209,6 +226,7 @@ case $state in '(-p,--package)'{-p=,--package=}'[package to update]:packages:__get_package_names' \ '--precise=[update single dependency to PRECISE]: :' \ '(-v, --verbose)'{-v,--verbose}'[use verbose output]' \ + '--color=[colorization option]' \ ;; verify-project) @@ -216,12 +234,14 @@ case $state in '(-h, --help)'{-h,--help}'[show help message]' \ '--manifest-path=[path to manifest]' \ '(-v, --verbose)'{-v,--verbose}'[use verbose output]' \ + '--color=[colorization option]' \ ;; version) _arguments \ '(-h, --help)'{-h,--help}'[show help message]' \ '(-v, --verbose)'{-v,--verbose}'[use verbose output]' \ + '--color=[colorization option]' \ ;; yank) @@ -231,6 +251,7 @@ case $state in '--token[API token]' \ '--undo[undo yank]' \ '(-v, --verbose)'{-v,--verbose}'[use verbose output]' \ + '--color=[colorization option]' \ '--vers[yank version]' \ ;; esac diff --git a/src/etc/cargo.1 b/src/etc/cargo.1 index 4d41efd9e..25aade5f4 100644 --- a/src/etc/cargo.1 +++ b/src/etc/cargo.1 @@ -26,6 +26,9 @@ List all available cargo commands .TP \fB\-v, \-\-verbose\fR Use verbose output +.TP +\fB\-\-color\fR +Configure coloring of output .SH COMMANDS diff --git a/src/etc/cargo.bashcomp.sh b/src/etc/cargo.bashcomp.sh index 968601365..3924e1e31 100644 --- a/src/etc/cargo.bashcomp.sh +++ b/src/etc/cargo.bashcomp.sh @@ -13,7 +13,8 @@ _cargo() local opt_help='-h --help' local opt_verbose='-v --verbose' local opt_quiet='-q --quiet' - local opt_common="$opt_help $opt_verbose $opt_quiet" + local opt_color='--color' + local opt_common="$opt_help $opt_verbose $opt_quiet $opt_color" local opt_pkg='-p --package' local opt_feat='--features --no-default-features' local opt_mani='--manifest-path' diff --git a/tests/test_shell.rs b/tests/test_shell.rs index 630a74d09..d3ee5f591 100644 --- a/tests/test_shell.rs +++ b/tests/test_shell.rs @@ -5,7 +5,7 @@ use term::{Terminal, TerminfoTerminal, color}; use hamcrest::{assert_that}; use cargo::core::shell::{Shell, ShellConfig}; -use cargo::core::shell::Verbosity::{Verbose, Quiet}; +use cargo::core::shell::ColorConfig::{Auto,Always, Never}; use support::{Tap, shell_writes}; @@ -22,7 +22,7 @@ impl Write for Sink { } test!(non_tty { - let config = ShellConfig { color: true, verbosity: Verbose, tty: false }; + let config = ShellConfig { color_config: Auto, tty: false }; let a = Arc::new(Mutex::new(Vec::new())); Shell::create(Box::new(Sink(a.clone())), config).tap(|shell| { @@ -34,7 +34,10 @@ test!(non_tty { }); test!(color_explicitly_disabled { - let config = ShellConfig { color: false, verbosity: Verbose, tty: true }; + let term = TerminfoTerminal::new(Vec::new()); + if term.is_none() { return } + + let config = ShellConfig { color_config: Never, tty: true }; let a = Arc::new(Mutex::new(Vec::new())); Shell::create(Box::new(Sink(a.clone())), config).tap(|shell| { @@ -48,7 +51,7 @@ test!(colored_shell { let term = TerminfoTerminal::new(Vec::new()); if term.is_none() { return } - let config = ShellConfig { color: true, verbosity: Verbose, tty: true }; + let config = ShellConfig { color_config: Auto, tty: true }; let a = Arc::new(Mutex::new(Vec::new())); Shell::create(Box::new(Sink(a.clone())), config).tap(|shell| { @@ -60,17 +63,20 @@ test!(colored_shell { color::RED).unwrap())); }); -test!(quiet_shell { - let config = ShellConfig { color: true, verbosity: Quiet, tty: true }; +test!(color_explicitly_enabled { + let term = TerminfoTerminal::new(Vec::new()); + if term.is_none() { return } + + let config = ShellConfig { color_config: Always, tty: false }; let a = Arc::new(Mutex::new(Vec::new())); Shell::create(Box::new(Sink(a.clone())), config).tap(|shell| { - shell.say("Should be suppressed", color::BLACK).unwrap(); + shell.say("Hey Alex", color::RED).unwrap(); }); - let buf = a.lock().unwrap().clone(); assert_that(&buf[..], - shell_writes("")); + shell_writes(colored_output("Hey Alex\n", + color::RED).unwrap())); }); fn colored_output(string: &str, color: color::Color) -> io::Result { -- 2.30.2